#ifndef _GOFS_H_
#define _GOFS_H_

#define FUSE_USE_VERSION 26
#include "stdio.h"
#include "stdlib.h"
#include <unistd.h>
#include "fcntl.h"
#include "string.h"
#include "fuse.h"
#include <stddef.h>
#include "ddriver.h"
#include "errno.h"
#include "types.h"

#define GOFS_MAGIC   0xdead         /* TODO: Define by yourself */
#define GOFS_DEFAULT_PERM    0777   /* 全权限打开 */

/******************************************************************************
* SECTION: gofs.c
*******************************************************************************/
void* 			   gofs_init(struct fuse_conn_info *);
void  			   gofs_destroy(void *);
int   			   gofs_mkdir(const char *, mode_t);
int   			   gofs_getattr(const char *, struct stat *);
int   			   gofs_readdir(const char *, void *, fuse_fill_dir_t, off_t,
						                struct fuse_file_info *);
int   			   gofs_mknod(const char *, mode_t, dev_t);
int   			   gofs_write(const char *, const char *, size_t, off_t,
					                  struct fuse_file_info *);
int   			   gofs_read(const char *, char *, size_t, off_t,
					                 struct fuse_file_info *);
int   			   gofs_access(const char *, int);
int   			   gofs_unlink(const char *);
int   			   gofs_rmdir(const char *);
int   			   gofs_rename(const char *, const char *);
int   			   gofs_utimens(const char *, const struct timespec tv[2]);
int   			   gofs_truncate(const char *, off_t);
			
int   			   gofs_open(const char *, struct fuse_file_info *);
int   			   gofs_opendir(const char *, struct fuse_file_info *);

/******************************************************************************
* SECTION: macro debug
*******************************************************************************/
#define GOFS_DBG(fmt, ...) do { printf("GOFS_DBG: " fmt, ##__VA_ARGS__); } while(0) 
/******************************************************************************
* SECTION: gofs_utils.c
*******************************************************************************/
char* 			   gofs_get_fname(const char* path);
int 			   gofs_calc_lvl(const char * path);
int 			   gofs_driver_read(int offset, uint8_t *out_content, int size);
int 			   gofs_driver_write(int offset, uint8_t *in_content, int size);


int 			   gofs_mount(struct custom_options options);
int 			   gofs_umount();

int 			   gofs_append_dentry(struct gofs_inode * inode, struct gofs_dentry * dentry);
int 			   gofs_drop_dentry(struct gofs_inode * inode, struct gofs_dentry * dentry);
struct gofs_inode*  gofs_alloc_inode(struct gofs_dentry * dentry);
int 			   gofs_sync_inode(struct gofs_inode * inode);
int 			   gofs_drop_inode(struct gofs_inode * inode);
struct gofs_inode*  gofs_read_inode(struct gofs_dentry * dentry, int ino);
struct gofs_dentry* gofs_get_dentry(struct gofs_inode * inode, int dir);

struct gofs_dentry* gofs_lookup(const char * path, boolean * is_find, boolean* is_root);
/******************************************************************************
* SECTION: gofs.c
*******************************************************************************/
void* 			   gofs_init(struct fuse_conn_info *);
void  			   gofs_destroy(void *);
int   			   gofs_mkdir(const char *, mode_t);
int   			   gofs_getattr(const char *, struct stat *);
int   			   gofs_readdir(const char *, void *, fuse_fill_dir_t, off_t,
						       struct fuse_file_info *);
int   			   gofs_mknod(const char *, mode_t, dev_t);
int   			   gofs_write(const char *, const char *, size_t, off_t,
					         struct fuse_file_info *);
int   			   gofs_read(const char *, char *, size_t, off_t,
					        struct fuse_file_info *);
int   			   gofs_unlink(const char *);
int   			   gofs_rmdir(const char *);
int   			   gofs_rename(const char *, const char *);
int   			   gofs_utimens(const char *, const struct timespec tv[2]);
int   			   gofs_truncate(const char *, off_t);
int 			   gofs_symlink(const char *, const char *);
int 			   gofs_readlink(const char *, char *, size_t);
			
int   			   gofs_open(const char *, struct fuse_file_info *);
int   			   gofs_opendir(const char *, struct fuse_file_info *);
int   			   gofs_access(const char *, int);

int			       bmap(struct gofs_inode *ip, uint bn);
int 		   	   balloc();
/******************************************************************************
* SECTION: gofs_debug.c
*******************************************************************************/
void 			   gofs_dump_map();
#endif  /* _gofs_H_ */